/*! \file COMPointer.h
 *	\brief <write description for COMPointer.h>
 *
 *	created:	2009/11/16
 *	created:	16:11:2009   12:41
 *	filename: 	o:\main\libs\utils\COMPointer.h
 *	file path:	o:\main\libs\utils
 *	file base:	COMPointer
 *	file ext:	h
 *	author:		Vitalii Trubchaninov
 *				venngraydog@gmail.com
 */

#ifndef _UTILS_COMPOINTER_H_
#define _UTILS_COMPOINTER_H_

#pragma once

namespace tt{
namespace utils{

/*! Helper template class to wrap COM pointers in order to manage proper
	calls to AddRef and Release on construction, copy of pointers, etc
*/
template <class COMPointerT>
class COMPointer
{
public:
	typedef COMPointerT	COMPointerType;

	explicit COMPointer(COMPointerType* pCOMObject = NULL);
	COMPointer(const COMPointer& rhs);
	~COMPointer();

	void reset(COMPointerType* pCOMObject = NULL);

	COMPointer& operator=(const COMPointer&);
	void swap(COMPointer&);

	operator bool () const;

	COMPointerType* get();
	const COMPointerType* get() const;

	COMPointerType** getRef();

	COMPointerType* operator->();
	const COMPointerType* operator->() const;
	COMPointerType& operator*();
	const COMPointerType& operator*() const;

	bool operator==(const COMPointer& rhs) const;
	bool operator!=(const COMPointer& rhs) const;

private:
	COMPointerType*	m_pCOMObject;
};

template<typename COMPointerT>
HRESULT CoCreateInstance(REFCLSID rclsid,
						 LPUNKNOWN pUnkOuter,
						 DWORD dwClsContext,
						 REFIID riid,
						 COMPointer<COMPointerT>&);

} //namespace utils
} //namespace tt

#include "COMPointer.inl"

#endif //_UTILS_COMPOINTER_H_
